/*
Copyright 2007 Raymond Giorgi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */

package edu.pitt.CS2510.Nodes;

import java.util.ArrayList;

import edu.pitt.CS2510.Coordinate;
import edu.pitt.CS2510.Simulator;
import edu.pitt.CS2510.Grids.Grid;
import edu.pitt.CS2510.Messages.Message;
import edu.pitt.CS2510.NodeActions.NodeActions;
import edu.pitt.CS2510.NodeActions.NodeActionsInterface;

/**
 * @author Alichino
 * 
 *         Central, Supervisor, and Grunt (Worker) nodes all inherit from this
 *         class It defines some basic behavior used by all nodes
 */
public abstract class Node {
	protected Simulator simulator;
	protected Grid grid;
	protected NodeActions messageHandler = null;

	ArrayList<Message> messages = new ArrayList<Message>();

	/**
	 * Access to the simulator is required to send / recieve messages from other
	 * nodes
	 * 
	 * @param sim
	 * @param grid
	 */
	public Node(Simulator sim, Grid grid) {
		simulator = sim;
		this.grid = grid;
	}

	/**
	 * Send this message to another node. Information about where it's going is
	 * contained within the message itself.
	 * 
	 * @param m
	 */
	public void sendMessage(Message m) {
		simulator.sendMessage(m);
	}

	/**
	 * Receive a message from another node. Information about where it's coming
	 * from is contained within the message itself.
	 * 
	 * @param message
	 */
	public void recieveMessage(Message message) {
		messages.add(message);
	}

	/**
	 * All nodes must use this class so that the simulator can iterate over all
	 * nodes and tell them to perform their respective actions regardless of
	 * implementation
	 */
	public abstract void performAction();

	/**
	 * go through the message queue and take the appropriate action for every
	 * message type
	 */
	protected void processMessages() {
		for (Message m : messages) {
			m.processMessage(this);
			System.out.println(m.toString());
		}
		messages.clear();
	}

	/**
	 * 
	 * @return this node's version of the grid. It's kind of on the useless
	 *         side, but, whatever.
	 */
	public Grid getGrid() {
		return grid;
	}

	/**
	 * Used by the simulator to determine what type of node this is.
	 * 
	 * @return this node's message handler
	 */
	public NodeActionsInterface getMessageHandler() {
		return messageHandler;
	}

	/**
	 * 
	 * @param co
	 * @return the number of enemies at a coordinate
	 */
	public int getEnemiesAtCo(Coordinate co) {
		return simulator.getEnemiesAtCo(co);
	}

	/**
	 * 
	 * @return return the unique id of this node
	 */
	abstract public int getId();
}
